home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2001 September / PC-WELT 9-2001.ISO / software / hw / brennen / flask_src.exe / Video / VideoWrapper.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-19  |  25.2 KB  |  1,161 lines

  1. /* 
  2.  *  VideoWrapper.cpp 
  3.  *
  4.  *    Copyright (C) Alberto Vigata - January 2000  ultraflask@yahoo.com
  5.  *                 
  6.  *
  7.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  8.  *    
  9.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  10.  *  it under the terms of the GNU General Public License as published by
  11.  *  the Free Software Foundation; either version 2, or (at your option)
  12.  *  any later version.
  13.  *   
  14.  *  FlasKMPEG is distributed in the hope that it will be useful,
  15.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *  GNU General Public License for more details.
  18.  *   
  19.  *  You should have received a copy of the GNU General Public License
  20.  *  along with GNU Make; see the file COPYING.  If not, write to
  21.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  22.  *
  23.  */
  24.  
  25.  
  26. #include "VideoWrapper.h"
  27. #include "..\Subpic\Subpic.h"
  28.  
  29. extern "C"
  30. {
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <ctype.h>
  34. #include <fcntl.h>
  35. #include <assert.h>
  36.  
  37. #define GLOBAL
  38. #include "config.h"
  39. #include "global.h"
  40. }
  41.  
  42. #define ABS(x) ((x>0)? x:-x)
  43.  
  44.  
  45. //Global variables for syncing with decoding thread
  46. VideoWrapper *myVideo;
  47. __int64      rawPTS[1024];
  48. int             gopPOS;
  49. bool         closedGOP;
  50. bool         synced=false;
  51. int             gopNum;
  52.  
  53. /* private prototypes */
  54. static int  video_sequence _ANSI_ARGS_((int *framenum));
  55. static int Decode_Bitstream _ANSI_ARGS_((void));
  56. static int  Headers _ANSI_ARGS_((void));
  57. static void        Initialize_Sequence _ANSI_ARGS_((void));
  58. static void Initialize_Decoder _ANSI_ARGS_((void));
  59.        void Deinitialize_Sequence _ANSI_ARGS_((void));
  60. static void Process_Options _ANSI_ARGS_((int argc, char *argv[]));
  61. static void InitClip();
  62. static void DeInitClip();
  63. void NextSequenceHeader(){
  64.     while (Show_Bits(32)!=0x000001B3)
  65.         Flush_Buffer(1);
  66. }
  67. #define RESERVED 1
  68. static double MPEG1aspect_ratio_Table[16] =
  69. {
  70.     0.0,    
  71.     1.0000,
  72.     0.6735,        
  73.     0.7031,
  74.     0.7615,        
  75.     0.8055,        
  76.     0.8437,
  77.     0.8935,        
  78.     0.9375,
  79.     0.9815,        
  80.     1.0255,        
  81.     1.0695,        
  82.     1.1250,
  83.     1.1575,        
  84.     1.2015,
  85.     RESERVED
  86. };
  87. char *MPEG1aspectStrings[16]=
  88.                 { "Unexpected"      , "1.0 Square Sample",    "SAR 0.6735",     "16:9 PAL",
  89.                   "SAR 0.7615"      , "SAR 0.8055",           "16:9 NTSC",      "SAR 0.8935",
  90.                   "4:3 CCIR601 PAL" , "SAR 0.9815",           "1.0255",         "1.0695",
  91.                   "4:3 CCIR601 NTSC", "",                     "",               ""};
  92.  
  93. static double frameRateTable[16]=
  94. {
  95.   0.0,
  96.   (24000.0/1001.0),
  97.   24.0,
  98.   25.0,
  99.   (30000.0/1001.0),
  100.   30.0,
  101.   50.0,
  102.   (60000.0/1001.0),
  103.   60.0,
  104.   0.0,
  105.   0.0,
  106.   0.0,
  107.   0.0,
  108.   0.0,
  109.   0.0,
  110.   0.0
  111. };
  112.  
  113. static double MPEG2aspect_ratio_Table[16] =
  114. {
  115.   0.0,
  116.   1,
  117.   (3.0/4.0),
  118.   (9.0/16.0),
  119.   (1.0/2.21),
  120.   RESERVED,
  121.   RESERVED,
  122.   RESERVED,
  123.   RESERVED,
  124.   RESERVED,
  125.   RESERVED,
  126.   RESERVED,
  127.   RESERVED,
  128.   RESERVED,
  129.   RESERVED,
  130.   RESERVED
  131. };
  132.  
  133. char *MPEGframeRateStrings[16]={
  134.                 "Unexpected",
  135.                 "FILM at 23.976 fps", 
  136.                 "FILM at 24 fps",   
  137.                 "PAL at 25 fps",
  138.                 "NTSC at 29.97 fps", 
  139.                 "NTSC at 30 fps",     
  140.                 "PAL at 50 fps",    
  141.                 "NTSC at 59.94 fps",
  142.                 "NTSC at 60 fps",
  143.                 "","","","","","",""
  144. };
  145.  
  146. char *MPEG2aspectStrings[16]=
  147.                 {"Unexpected", "1.0 Square Sample", "4:3","16:9",
  148.                 "2.21:1","","","",
  149.                 "","","","",
  150.                 "","","",""};
  151.  
  152. int init_recons(TRecImage *image, int xsize, int ysize)
  153. {
  154.     if(image){
  155.         image->im.Y = (YUVPixel *)malloc(xsize*ysize);
  156.         image->im.U = (YUVPixel *)malloc((xsize*ysize)>>2);
  157.         image->im.V = (YUVPixel *)malloc((xsize*ysize)>>2);
  158.         image->im.Yxsize = xsize;
  159.         image->im.Yysize = ysize;
  160.         image->im.Cxsize = xsize>>1;
  161.         image->im.Cysize = ysize>>1;
  162.         image->state = FREE;
  163.         return 1;
  164.     }
  165.     else
  166.         return 0;
  167.  
  168. }
  169.  
  170. void deinit_recons(TRecImage *image)
  171. {
  172.     if( image ){
  173.         free(image->im.Y);
  174.             image->im.Y = NULL;
  175.         free(image->im.U);
  176.             image->im.U = NULL;
  177.         free(image->im.V);
  178.             image->im.V = NULL;
  179.     }
  180. }
  181. VideoWrapper::VideoWrapper(char *inputFile, int streamID, int subStreamID,                
  182.                            int subpic_streamID, int subpic_substreamID, int mode)
  183. {
  184.     int code,ret;
  185.  
  186.     VideoWrapper::streamID    = streamID;
  187.     VideoWrapper::subStreamID = subStreamID;
  188.  
  189.     VideoWrapper::subpic_streamID    = subpic_streamID;
  190.     VideoWrapper::subpic_substreamID = subpic_substreamID;
  191.     
  192.     time=0;
  193.     error=0;
  194.     pictureWidth=0;
  195.     picutreHeight=0;
  196.     myVideo=this;
  197.     stopDecoding=false;
  198.     //Do inits 
  199.     ld = &base; /* select base layer context */    
  200.     Frame_Store_Flag = 1;
  201.     Output_Type=2;
  202.     Output_Picture_Filename="pic%d";
  203.     System_Stream_Flag = 0;
  204.     
  205.     //Start demuxer
  206.     SetInput(inputFile);
  207.     //GuessTotalFrames()
  208.     //STARTING DECODER
  209.     InitClip();
  210.     inp->SetStreamPos(0);
  211.     //GUESS STREAM TYPE
  212.     StartReadLPES();
  213.     Initialize_Buffer();
  214.     next_start_code();
  215.     code = Show_Bits(32);
  216.     switch(code)
  217.     {
  218.     case SEQUENCE_HEADER_CODE:
  219.       break;
  220.     case PACK_START_CODE:
  221.       System_Stream_Flag = 1;
  222.     case VIDEO_ELEMENTARY_STREAM:
  223.       System_Stream_Flag = 1;
  224.       break;
  225.     default:
  226.       sprintf(Error_Text,"Unable to recognize stream type\n");
  227.       Error(Error_Text);
  228.       break;
  229.     }
  230.  
  231.  
  232.     detectFrameRate();
  233.     //GET  SEQUENCE PROPERTIES
  234.     inp->SetStreamPos(0);
  235.     StartReadLPES();
  236.     Initialize_Buffer(); 
  237.     Initialize_Decoder();
  238.     NextSequenceHeader();
  239.      /* Headers returns when end of sequence (0) or picture
  240.      header has been parsed (1) */
  241.     ret = Headers();
  242.     if(ret==1)
  243.     {
  244.     /*video_sequence(&Bitstream_Framenum);*/
  245.       //VIDEO SEQUENCE....
  246.           Sequence_Framenum=0;
  247.         Initialize_Sequence();
  248.         pictureWidth=Coded_Picture_Width;
  249.         picutreHeight=Coded_Picture_Height;
  250.         updateVideoStats();
  251.  
  252.         init_recons(&reca, pictureWidth, picutreHeight);
  253.         init_recons(&recb, pictureWidth, picutreHeight);
  254.         //Deinitialize_Sequence();
  255.     }
  256.     inp->SetStreamPos(0);
  257.     StartReadLPES();
  258.     Initialize_Buffer(); 
  259.     synced=true;
  260.     // Allocate memory for reconstruted images
  261.  
  262.  
  263. }
  264.  
  265. VideoWrapper::~VideoWrapper()
  266. {
  267.     // Deallocating memory
  268.     deinit_recons(&reca);
  269.     deinit_recons(&recb);
  270.  
  271.     DeInitClip();
  272.     Deinitialize_Sequence();
  273. }
  274.  
  275. VideoWrapper::Start(TVideoOptions *opt)
  276. {
  277.     //Retrieve first sequence_header parameters
  278.  
  279.  
  280.     ResetRawPTS();
  281.     time=0;
  282.  
  283.     justStarted = true;
  284.     //Read Linear PES init
  285.     StartReadLPES();
  286.     //Decoder Configuration
  287.     timeCode.frame=0;
  288.     timeCode.hour=0;
  289.     timeCode.minute=0;
  290.     timeCode.second=0;
  291.     stopDecoding=false;
  292.     VideoWrapper::idctType = opt->idctType;
  293.     recons_progressive     = opt->recons_progressive;
  294.  
  295.     //PTS variables
  296.     TFrameInfo temp;
  297.     temp.PTS = 0;
  298.     temp.SCR = 0;
  299.     p.actual   = temp;
  300.     p.backward = temp;
  301.     p.fordward = temp;
  302.     p.image    = temp;
  303.  
  304.     outGopPos=0;
  305.     internalPTS=0;
  306.     PTSlocked=false;
  307.     SCRlocked=true;
  308.     // Pull down stuff
  309.     pullDownDetected=false;
  310.     pulldown_state  = 3;
  311.     interlaced_field_delay = (__int64)(MPEG2_CLK_REF*(frameDelay))>>1;
  312.    progressive_frame_delay = (__int64)(MPEG2_CLK_REF*(1.25*frameDelay));
  313.  
  314.     seqIsProgressive=false;
  315.     previousPicSCR=0;
  316.     prevProgressiveFrame=progressive_sequence;
  317.     prevRepeatFirstField=0;
  318.  
  319. //    if(synced==false)
  320.         gopNum= -1;
  321.  
  322.     Bitstream_Framenum = 0;
  323.     Initialize_Decoder();
  324.     sequencePos=SEQ_FIRSTTIME;
  325.  
  326.     // Double Buffer
  327.     reca.state = FREE;
  328.     recb.state = FREE;
  329.     dbuf.rec[0] = &reca;
  330.     dbuf.rec[1] = &recb;
  331.     image_zero(&reca.im);
  332.     image_zero(&recb.im);
  333.  
  334.     // Subpic init
  335.     subpic_init();
  336.  
  337.     return 0;
  338. }
  339.  
  340. #define IMAGE_COPY(x)   image_copy(&dbuf.rec[x]->im, &YUV)
  341. #define FIELD_COPY(x,y) field_copy(&dbuf.rec[x]->im, &YUV, y)
  342. #define FIELD_COPY_SWAP(x,y) field_copy_swap(&dbuf.rec[x]->im, &YUV, y)
  343. #define GET_DB(x)  (&dbuf.rec[x]->im)
  344. #define GET_PTS(x)  (dbuf.rec[x]->PTS)
  345. #define SET_PTS(x,y)  (dbuf.rec[x]->PTS=y)
  346. #define SET_FREE(x)    (dbuf.rec[x]->state  =  FREE)
  347. #define SET_FULL(x) (dbuf.rec[x]->state  =  FULL)
  348. #define DB_0 0
  349. #define DB_1 1
  350. void VideoWrapper::swap_db()
  351. {
  352.         TRecImage *temp;
  353.         temp        = dbuf.rec[0];
  354.         dbuf.rec[0] = dbuf.rec[1];
  355.         dbuf.rec[1] = temp;    
  356.  
  357. }
  358. i64 inline VideoWrapper::get_time(int adjust_clock)
  359. {
  360.     i64    present;
  361.     i64    delay = (__int64)(MPEG2_CLK_REF*(frameDelay));
  362.     ui32  half_delay = (int)delay>>1;
  363.  
  364.     if(p.image.PTS){
  365.         internalPTS = p.image.PTS;
  366.         if(adjust_clock==EQUAL)
  367.             present = internalPTS;
  368.         if(adjust_clock==PLUS)
  369.             present = internalPTS = internalPTS + half_delay;
  370.         if(adjust_clock==MINUS)
  371.             present = internalPTS = internalPTS - half_delay;
  372.             internalPTS += i64(recons_progressive ? (1.25*(double)delay) : delay);    
  373.  
  374.     }
  375.     else{
  376.             present = internalPTS;
  377.             internalPTS += i64(recons_progressive ? (1.25*(double)delay) : delay);    
  378.     }
  379.     return present;
  380. }
  381.  
  382. int  VideoWrapper::guess_32pulldown(){
  383.  
  384.     // pulldown_state: input picture state
  385.     //
  386.     //  3:2 pulldown frames source
  387.     //  T: top field      B: bottom field
  388.     //
  389.     //  1st     2nd     3d      4th
  390.     //
  391.     //  TBT     BT      BTB      TB
  392.     //
  393.     //  4 states
  394.     if(progressive_sequence){
  395.         pullDownDetected = false;
  396.         pulldown_state = 3;
  397.     }
  398.     else{
  399.         if(p.image.progressive_frame)
  400.         {
  401.             if(p.image.top_field_first){
  402.                 switch( pulldown_state )
  403.                 {
  404.                     case 0:
  405.                         pullDownDetected = false;
  406.                         pulldown_state   = 3;
  407.                         break;
  408.                     case 1:
  409.                         pullDownDetected = false;
  410.                         pulldown_state   = 3;
  411.                         break;
  412.                     case 2:
  413.                         if(!p.image.repeat_first_field){
  414.                             //Yehaa!!
  415.                             pulldown_state   = 3;
  416.                             pullDownDetected = true;
  417.                         }
  418.                         else{
  419.                             pulldown_state   = 3;
  420.                             pullDownDetected = false;
  421.                         }
  422.                         break;
  423.                     case 3:
  424.                         //First in sequence
  425.                         if(p.image.repeat_first_field){
  426.                             pulldown_state   = 0;
  427.                         }
  428.                         else{
  429.                             pulldown_state   = 3;
  430.                             pullDownDetected = false;
  431.                         }
  432.                         break;
  433.                 }
  434.             }
  435.             else{  //Bottom field first
  436.                 switch( pulldown_state )
  437.                 {
  438.                     case 0:
  439.                         if(p.image.repeat_first_field){
  440.                             pulldown_state   = 3;
  441.                             pullDownDetected = false;
  442.                         }
  443.                         else
  444.                             pulldown_state  = 1;
  445.                         break;
  446.                     case 1:
  447.                         if(p.image.repeat_first_field)
  448.                             pulldown_state  = 2;
  449.                         else{
  450.                             pulldown_state   = 3;
  451.                             pullDownDetected = false;
  452.                         }
  453.                         break;
  454.                     case 2:
  455.                             pulldown_state   = 3;
  456.                             pullDownDetected = false;
  457.                         break;
  458.                     case 3:
  459.                             pulldown_state   = 3;
  460.                             pullDownDetected = false;
  461.                         break;
  462.                 }
  463.             }
  464.         }
  465.         else{
  466.             pullDownDetected = false;
  467.             pulldown_state = 3;
  468.         }    
  469.     }
  470.     return 0;
  471. }
  472. void VideoWrapper::adjust_pulldown_timing(){
  473.  
  474.  
  475.  
  476.     // 24 fps sequence
  477.     //  
  478.     //  [--------][-------][------][------]
  479.     //  [  |  ][  |  ][  |  ][  |  ][  |  ]
  480.     if(p.image.PTS){
  481.         switch(pulldown_state)
  482.         {
  483.             case 0:
  484.                 //32 PTS equals real one
  485.                 break;
  486.             case 1:
  487.                 // PTS for 3 fields of 3:2 sequence
  488.                 p.image.PTS = p.image.PTS - 3*interlaced_field_delay + progressive_frame_delay;
  489.                 break;
  490.             case 2:
  491.                 //3:2 PTS equals the real one                
  492.                 break;
  493.             case 3:
  494.                 p.image.PTS = p.image.PTS - 8*interlaced_field_delay + 3*progressive_frame_delay;
  495.                 break;
  496.         }
  497.     }
  498. }
  499. VideoWrapper::GetFrame(presInfo *pInfo, YUVImageTag **frame)
  500. {
  501.  
  502.     int val;
  503.     ui64  frame_delay = (__int64)(MPEG2_CLK_REF*(frameDelay));
  504.  
  505.     *frame = NULL;
  506.  
  507.     // if there are full frames in the double buffer
  508.     //    output them
  509.     if(dbuf.rec[0]->state == FULL){
  510.         //Return frame 0
  511.         //Swap buffers and signal as FREE
  512.         dbuf.rec[0]->state = FREE;
  513.         *frame = &dbuf.rec[0]->im;
  514.         pInfo->imagePTS = GET_PTS(0);
  515.         swap_db();
  516.         return 1;
  517.     }
  518.     val = get_frame();
  519.     if(!val)
  520.         return 0;
  521.  
  522.     //if(recons_progressive){
  523.     //    guess_32pulldown();
  524.     //    if(!pullDownDetected)
  525.     //        int i=0;
  526.             //adjust_pulldown_timing();
  527.     //}
  528.     //else{
  529.     //    pullDownDetected = false;
  530.     //}
  531.     // if partially reconstructed frame
  532.     //    if(dbuf.rec[0]->state != FREE){
  533.     //the picture has either bottom or top field reconstructed
  534.     if(progressive_sequence){
  535.         //Well, here MPEG2 standard defines 
  536.         // to output 1, 2 or 3 consecutive frames
  537.         // for 60 fps progressive output
  538.         // let's output just one
  539.         // This is the case of MPEG1 too
  540.         IMAGE_COPY(0);
  541.         SET_PTS(0, get_time(EQUAL) );
  542.         dbuf.rec[0]->state  =  FREE;
  543.         *frame = GET_DB(0);
  544.         pInfo->imagePTS = GET_PTS(0);
  545.  
  546.         goto get_frame_end;
  547.     }
  548.     else{
  549.         if(p.image.progressive_frame)
  550.         {
  551.             if(recons_progressive){
  552.  
  553.                 IMAGE_COPY(0);
  554.                 SET_PTS(0, get_time(EQUAL));
  555.                 dbuf.rec[0]->state  =  FREE;
  556.  
  557.                 *frame = GET_DB(0);
  558.                 pInfo->imagePTS = GET_PTS(0);
  559.                 goto get_frame_end;
  560.             }
  561.  
  562.             if(p.image.top_field_first){
  563.  
  564.                 IMAGE_COPY(0);
  565.                 SET_PTS(0, get_time(EQUAL));
  566.                 dbuf.rec[0]->state  =  FREE;
  567.                 if(p.image.repeat_first_field ){
  568.                     FIELD_COPY(1, TOP_FIELD);
  569.                     dbuf.rec[1]->state  =  TOP_FIELD;
  570.                 }
  571.                 *frame = GET_DB(0);
  572.                 pInfo->imagePTS = GET_PTS(0);
  573.  
  574.                 swap_db();
  575.                 goto get_frame_end;
  576.             }
  577.             else{//Bottom field first
  578.  
  579.                 FIELD_COPY(0, BOTTOM_FIELD);
  580.                 SET_PTS(0, get_time(MINUS) );
  581.                 SET_FREE(0);
  582.                 if(justStarted)
  583.                     FIELD_COPY_SWAP(0, BOTTOM_FIELD);
  584.  
  585.                 FIELD_COPY(1, TOP_FIELD);
  586.                 dbuf.rec[1]->state = TOP_FIELD;
  587.                 if(p.image.repeat_first_field ){
  588.                     FIELD_COPY(1, BOTTOM_FIELD);
  589.                     // Reset PTS for the repeat_first_field if any
  590.                     p.image.PTS = 0;
  591.                     SET_PTS(1, get_time(EQUAL) );
  592.                     SET_FULL(1);
  593.                 }
  594.                 *frame = GET_DB(0);
  595.                 pInfo->imagePTS = GET_PTS(0);
  596.  
  597.                 swap_db();
  598.                 goto get_frame_end;
  599.             }
  600.         }
  601.         else{
  602.             if( p.image.picture_structure == FRAME_PICTURE ){
  603.                 if(p.image.top_field_first){
  604.                     IMAGE_COPY(0);
  605.                     SET_PTS(0, get_time(EQUAL));
  606.                     SET_FREE(0);
  607.                     *frame = GET_DB(0);
  608.                     pInfo->imagePTS = GET_PTS(0);
  609.  
  610.                     goto get_frame_end;
  611.                 }
  612.                 else{//bottom field first
  613.                     FIELD_COPY(0, BOTTOM_FIELD);
  614.                     SET_PTS(0, get_time(MINUS) );
  615.                     SET_FREE(0);
  616.                     if(justStarted)
  617.                         FIELD_COPY_SWAP(0, BOTTOM_FIELD);
  618.  
  619.  
  620.                     FIELD_COPY(1, TOP_FIELD);
  621.                     dbuf.rec[1]->state  =  TOP_FIELD;
  622.                     *frame = GET_DB(0);
  623.                     pInfo->imagePTS = GET_PTS(0);
  624.  
  625.                     swap_db();
  626.                     goto get_frame_end;
  627.                 }
  628.             }
  629.             else{
  630.                 if(p.image.picture_structure == TOP_FIELD){
  631.                     IMAGE_COPY(DB_0);
  632.                     SET_PTS(0, get_time(EQUAL) );
  633.                     SET_FREE(0);
  634.                     *frame = GET_DB(0);
  635.                     pInfo->imagePTS = GET_PTS(0);
  636.     
  637.                     goto get_frame_end;
  638.                 }
  639.                 else{//field picture. BOTTOM FIELD
  640.                     FIELD_COPY(DB_0, BOTTOM_FIELD);
  641.                     SET_PTS(0, get_time(MINUS) );
  642.                     SET_FREE(0);
  643.                     if(justStarted)
  644.                         FIELD_COPY_SWAP(0, BOTTOM_FIELD);
  645.  
  646.                     FIELD_COPY(DB_1, TOP_FIELD);
  647.                     dbuf.rec[1]->state  =  TOP_FIELD;
  648.                     *frame = GET_DB(0);
  649.                     pInfo->imagePTS = GET_PTS(0);
  650.     
  651.                     swap_db();
  652.                     goto get_frame_end;
  653.                 }
  654.             }    
  655.         }
  656.     }
  657. get_frame_end:
  658.     justStarted = false;
  659.     return val;    
  660. }
  661.  
  662. int VideoWrapper::get_frame()
  663. {
  664.  //xsize, ysize: DibArray output sizes
  665.   //If Everything is OK
  666.   int ret;
  667.   //pictureWidth=Coded_Picture_Width;
  668.   //picutreHeight=Coded_Picture_Height;
  669.  
  670.   updateVideoStats();
  671.  
  672.   time= (ui32)(double(GetTime())/ (double)27000); //miliseconds
  673.   //In case  there is a problem
  674.     YUV.U=NULL;
  675.     YUV.V=NULL;
  676.     YUV.Y=NULL;
  677.     YUV.Yxsize=-1;
  678.   timeCode.hour= hour;
  679.   timeCode.minute= minute;
  680.   timeCode.second= sec;
  681.   timeCode.frame=  frame;
  682.  
  683.   if(stopDecoding){
  684.         error=PLAYER_STOPPED;
  685.         return 0;
  686.   }
  687.  
  688. decode_picture_begin:
  689.   switch( sequencePos )
  690.   {
  691.     case SEQ_FIRSTTIME:
  692.         
  693.  
  694.             goto start_sequence;    //This is the first time
  695.  
  696.       break;
  697.     case SEQ_FINISHED:
  698.  
  699. start_sequence:
  700.         ret = Headers();
  701.  
  702.         if(ret==1)
  703.         {
  704.             /*video_sequence(&Bitstream_Framenum);*/
  705.               //VIDEO SEQUENCE....
  706.  
  707.                 Sequence_Framenum=0;
  708.  
  709.                 /* decode picture whose header has already been parsed in 
  710.                 Decode_Bitstream() */
  711.                 ret=Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
  712.                 /* update picture numbers */
  713.                 if (!Second_Field)
  714.                 {
  715.                     Bitstream_Framenum++;
  716.                     Sequence_Framenum++;
  717.                 }
  718.                 sequencePos=SEQ_STARTED;
  719.                 if(ret==0)
  720.                     goto decode_picture_begin;
  721. //                updatePTS(pInfo);
  722.                 return 1;
  723.         }
  724.         else
  725.             goto end;  //End of bitstream file
  726.  
  727.         break;
  728.     case SEQ_STARTED:
  729.                 if((ret=Headers()))
  730.                 {
  731.                     ret = Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
  732.  
  733.                     //FileProgress.currentPosition=tell(base.Infile);
  734.                     if (!Second_Field)
  735.                     {
  736.                         Bitstream_Framenum++;
  737.                         Sequence_Framenum++;
  738.                     }
  739.  
  740.                     if(ret==0)
  741.                         goto decode_picture_begin;
  742. //                    updatePTS(pInfo);
  743.                     //
  744.                     return 1;
  745.                 }
  746.                 else
  747.                 {
  748.                     /* put last frame */
  749.                     if (Sequence_Framenum!=0)
  750.                     {
  751.                         Output_Last_Frame_of_Sequence(Bitstream_Framenum);
  752.                     }
  753.                     //Deinitialize_Sequence();
  754.                     isDecoding=false;
  755.                     #ifdef VERIFY
  756.                         Clear_Verify_Headers();
  757.                     #endif /* VERIFY */
  758.                     sequencePos=SEQ_FINISHED;
  759.  
  760.                     return 1;
  761.                 }
  762.  
  763.         break;
  764.   }
  765.  
  766. end:
  767.       error=END_OF_STREAM;
  768.       return 0;
  769. }
  770.  
  771.  
  772. VideoWrapper::Stop()
  773. {
  774.     time=0;
  775.     subpic_free(); /* reset subpics */
  776.     return 0;
  777. }
  778.  
  779. void DeInitClip(){
  780.     free(Clip-384);
  781. }
  782. void InitClip(){
  783.  
  784.   int i;
  785.  
  786.   /* Clip table */
  787.   if (!(Clip=(unsigned char *)malloc(1024)))
  788.     Error("Clip[] malloc failed\n");
  789.  
  790.   Clip += 384;
  791.  
  792.   for (i=-384; i<640; i++)
  793.     Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  794. }
  795.  
  796.  
  797. /* IMPLEMENTAION specific rouintes */
  798. static void Initialize_Decoder()
  799. {
  800.  
  801.  
  802.   //
  803.   gopPreviousPos=-1;
  804.   gop_count=512;
  805.  
  806.   /* IDCT */
  807.   if (myVideo->idctType==3)
  808.     Initialize_Reference_IDCT();
  809.   else if(myVideo->idctType==2)
  810.     Initialize_Fast_IDCT();
  811.  
  812. }
  813.  
  814. /* mostly IMPLEMENTAION specific rouintes */
  815. static void Initialize_Sequence()
  816. {
  817.   int cc, size;
  818.   static int Table_6_20[3] = {6,8,12};
  819.  
  820.   /* check scalability mode of enhancement layer */
  821.   if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
  822.     Error("unsupported scalability mode\n");
  823.  
  824.   /* force MPEG-1 parameters for proper decoder behavior */
  825.   /* see ISO/IEC 13818-2 section D.9.14 */
  826.   if (!base.MPEG2_Flag)
  827.   {
  828.     progressive_sequence = 1;
  829.     progressive_frame = 1;
  830.     picture_structure = FRAME_PICTURE;
  831.     frame_pred_frame_dct = 1;
  832.     chroma_format = CHROMA420;
  833.     matrix_coefficients = 5;
  834.   }
  835.  
  836.   /* round to nearest multiple of coded macroblocks */
  837.   /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
  838.   mb_width = (horizontal_size+15)/16;
  839.   mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
  840.                                         : (vertical_size+15)/16;
  841.  
  842.   Coded_Picture_Width = 16*mb_width;
  843.   Coded_Picture_Height = 16*mb_height;
  844.  
  845.     //Allocate space for Output Bitmap
  846.    //DibArray=malloc(         Coded_Picture_Width * Coded_Picture_Height * 3 );  
  847.     //DibArray = TempArray;
  848.  
  849.   /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
  850.   Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
  851.                                            : Coded_Picture_Width>>1;
  852.   Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
  853.                                             : Coded_Picture_Height>>1;
  854.   
  855.   /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
  856.   block_count = Table_6_20[chroma_format-1];
  857.  
  858.   for (cc=0; cc<3; cc++)
  859.   {
  860.     if (cc==0)
  861.       size = Coded_Picture_Width*Coded_Picture_Height;
  862.     else
  863.       size = Chroma_Width*Chroma_Height;
  864.  
  865.     if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
  866.       Error("backward_reference_frame[] malloc failed\n");
  867.  
  868.     if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
  869.       Error("forward_reference_frame[] malloc failed\n");
  870.  
  871.     if (!(auxframe[cc] = (unsigned char *)malloc(size)))
  872.       Error("auxframe[] malloc failed\n");
  873.  
  874.     if(Ersatz_Flag)
  875.       if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
  876.         Error("substitute_frame[] malloc failed\n");
  877.  
  878.  
  879.     if (base.scalable_mode==SC_SPAT)
  880.     {
  881.       /* this assumes lower layer is 4:2:0 */
  882.       if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
  883.         Error("llframe0 malloc failed\n");
  884.       if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
  885.         Error("llframe1 malloc failed\n");
  886.     }
  887.   }
  888.  
  889.   /* SCALABILITY: Spatial */
  890.   if (base.scalable_mode==SC_SPAT)
  891.   {
  892.     if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
  893.       Error("lltmp malloc failed\n");
  894.   }
  895.  
  896.  
  897.  
  898. }
  899.  
  900. void Error(char *text)
  901. {
  902.   fprintf(stderr,text);
  903. //  exit(1);
  904. }
  905.  
  906. /* Trace_Flag output */
  907. void Print_Bits(int code,int bits,int len)
  908. {
  909.   int i;
  910.   for (i=0; i<len; i++)
  911.     printf("%d",(code>>(bits-1-i))&1);
  912. }
  913.  
  914.  
  915.  
  916.  
  917. static int Headers()
  918. {
  919.   int ret;
  920.  
  921.   ld = &base;
  922.   
  923.  
  924.   /* return when end of sequence (0) or picture
  925.      header has been parsed (1) */
  926.  
  927.   ret = Get_Hdr();
  928.  
  929.  
  930.   if (Two_Streams)
  931.   {
  932.     ld = &enhan;
  933.     if (Get_Hdr()!=ret && !Quiet_Flag)
  934.       fprintf(stderr,"streams out of sync\n");
  935.     ld = &base;
  936.   }
  937.  
  938.   return ret;
  939. }
  940.  
  941.  
  942.  
  943. static int Decode_Bitstream()
  944. {
  945.   int ret;
  946.   int Bitstream_Framenum;
  947.  
  948.   Bitstream_Framenum = 0;
  949.  
  950.   for(;;)
  951.   {
  952.  
  953. #ifdef VERIFY
  954.     Clear_Verify_Headers();
  955. #endif /* VERIFY */
  956.  
  957.     ret = Headers();
  958.     
  959.     if(ret==1)
  960.     {
  961.       ret = video_sequence(&Bitstream_Framenum);
  962.     }
  963.     else
  964.       return(ret);
  965.   }
  966.  
  967. }
  968.  
  969.  
  970. void Deinitialize_Sequence()
  971. {
  972.   int i;
  973.  
  974.   /* clear flags */
  975.   base.MPEG2_Flag=0;
  976.  
  977.   for(i=0;i<3;i++)
  978.   {
  979.     free(backward_reference_frame[i]);
  980.     free(forward_reference_frame[i]);
  981.     free(auxframe[i]);
  982.  
  983.     if (base.scalable_mode==SC_SPAT)
  984.     {
  985.      free(llframe0[i]);
  986.      free(llframe1[i]);
  987.     }
  988.   }
  989.  
  990.   if (base.scalable_mode==SC_SPAT)
  991.     free(lltmp);
  992.  
  993. #ifdef DISPLAY
  994.   if (Output_Type==T_X11) 
  995.     Terminate_Display_Process();
  996. #endif
  997. }
  998.  
  999.  
  1000. static int video_sequence(int *Bitstream_Framenumber)
  1001. {
  1002. //  int Bitstream_Framenum;
  1003.  // int Sequence_Framenum;
  1004.   int Return_Value;
  1005.  
  1006.  
  1007.   return(Return_Value);
  1008. }
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014. int VideoWrapper::SeekVideo(__int64 pos)
  1015. {
  1016.     if(pos==0)
  1017.         synced=true;
  1018.     else
  1019.         synced=false;
  1020.     inp->SetStreamPos(pos);
  1021.     StartReadLPES();
  1022.     Initialize_Buffer();
  1023.  
  1024.     return 0;
  1025. }
  1026.  
  1027. int VideoWrapper::GetError()
  1028. {
  1029.     int temp;
  1030.     temp=error;
  1031.     error=0;
  1032.     return temp;
  1033. }
  1034.  
  1035. VideoWrapper::updateVideoStats()
  1036. {
  1037.         sprintf(sVideoSize, "%d x %d pixels", Coded_Picture_Width, Coded_Picture_Height);
  1038.         if(isMPEG2){
  1039.             DAR=MPEG2aspect_ratio_Table[aspect_ratio_information];
  1040.             strcpy(sAspectRatio,MPEG2aspectStrings[aspect_ratio_information]);
  1041.         }
  1042.         else{
  1043.             DAR=(MPEG1aspect_ratio_Table[aspect_ratio_information]*(double)picutreHeight)/((double)pictureWidth);
  1044.             strcpy(sAspectRatio,MPEG1aspectStrings[aspect_ratio_information]);
  1045.         }
  1046.         if(progressive_frame)
  1047.             strcpy(sProgressive, "Progressive");
  1048.         else
  1049.             strcpy(sProgressive, "Interlaced");
  1050.         sprintf(sBitrate, "%d bps",bit_rate_value*50*8);
  1051.         
  1052.         frameRate=frameRateTable[frame_rate_code];
  1053.         strcpy(sFrameRate, MPEGframeRateStrings[frame_rate_code]);
  1054.         
  1055.         detectedFrameRateCode=GetFrameRateCode(detectedFrameRate);
  1056.         strcpy(sDetectedFPS, MPEGframeRateStrings[detectedFrameRateCode]);
  1057.         
  1058.         detectedFrameDelay=1/frameRateTable[GetFrameRateCode(detectedFrameRate)];
  1059.         frameDelay=1/frameRate;
  1060.         sprintf(sBitrate, "%d bps",bit_rate_value*50*8);
  1061.  
  1062. }
  1063.  
  1064. void VideoWrapper::ResetRawPTS()
  1065. {
  1066. int i;
  1067.     for(i=0;i<1024;i++)
  1068.         rawPTS[i]=0;
  1069. }
  1070.  
  1071. int VideoWrapper::detectFrameRate()
  1072. {
  1073.     //This megamatic function will try to detect
  1074.     // the framerate of a stream, just looking into
  1075.     // the PTS from the incoming pictures.
  1076.     // This is necessary to detect 24 fps DVD progressive sequences
  1077.     // that have the frame_rate set to 29.97 and use repeat_first_field flag
  1078.     //
  1079.     //Guess stream rate if we are handling a MPEG2 file
  1080.     i64 fPTS,lPTS;
  1081.     int frames=0;
  1082.     int fGOPpos, lGOPpos;
  1083.     int ret;
  1084.     int gopsParsed;
  1085.  
  1086.     inp->SetStreamPos(0);
  1087.     StartReadLPES();
  1088.     Initialize_Buffer(); 
  1089.     
  1090.     //GopNum is updated everytime a Gop Header is parsed
  1091.     //gopFlag flags GOP headers. Must be manually reseted
  1092.       if(isMPEG2){
  1093.             //find first frame with a PTS
  1094.             do{
  1095.                 ret=Headers();
  1096.             }while((myPES.PTS==0 || picture_structure==2/*BOTTOM_FIELD*/)
  1097.                     && ret );
  1098.             fPTS=myPES.PTS;
  1099.             fGOPpos=temporal_reference;
  1100.             frames=0;
  1101.  
  1102.             //find next frame with a PTS greater than fPTS
  1103.             gopsParsed=0;
  1104.             do{
  1105.                 gopFlag=false;
  1106.                 ret=Headers();
  1107.                 if(gopFlag){
  1108.                     gopsParsed++;
  1109.                 }
  1110.             }while((myPES.PTS==0 || picture_structure==2/*BOTTOM_FIELD*/)
  1111.                     && ret    && myPES.PTS<=fPTS );
  1112.  
  1113.  
  1114.             lPTS=myPES.PTS;
  1115.             lGOPpos=temporal_reference;
  1116.  
  1117.             frames= gopsParsed ? ((gop_count-fGOPpos)+gop_count*(gopsParsed-1)+lGOPpos):(lGOPpos-fGOPpos);
  1118.             detectedFrameRate= 1/(((double)(lPTS-fPTS)/(double)frames)/(double)MPEG2_CLK_REF);
  1119.         }
  1120.         else{
  1121.                 ret=Headers();
  1122.             detectedFrameRate= frameRateTable[frame_rate_code];
  1123.         }
  1124.  
  1125.     return 1;
  1126. }
  1127.  
  1128. int VideoWrapper::GetFrameRateCode(double fr)
  1129. {
  1130.     double min_error,error;
  1131.     int frc,i;
  1132.     
  1133.     min_error=4096;
  1134.     for(i=1; i<=8; i++){
  1135.         error=ABS((frameRateTable[i]-fr));
  1136.         if(error<min_error){
  1137.             min_error=error;
  1138.             frc=i;
  1139.         }
  1140.     }
  1141.     return frc;
  1142. }
  1143.  
  1144.  
  1145. i64 VideoWrapper::GetVideoPos()
  1146. {
  1147.     return inp->GetStreamPos();
  1148. }
  1149.  
  1150. char *VideoWrapper::GetVideoFileName()
  1151. {
  1152.     return inp->GetFileName();
  1153. }
  1154.  
  1155. i64  VideoWrapper::GetVideoSize()
  1156. {
  1157.     return inp->GetStreamSize();
  1158. }
  1159.  
  1160.  
  1161.